package com.sl.controller;

import com.alibaba.druid.support.spring.stat.annotation.Stat;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.sl.entity.PageResult;
import com.sl.entity.Result;
import com.sl.entity.StatusCode;
import com.sl.pojo.CompanyCheck;
import com.sl.pojo.Document;
import com.sl.service.DocumentService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/file")
public class DocumentController {

    @Value("${upload.url}")
    private String uploadUrl;
    @Value("${domain}")
    private String domain;
    @Autowired
    private DocumentService documentService;

    @GetMapping("/download/{docId}")
    public void download(@PathVariable String docId, HttpServletResponse response) {
        try {
            log.info(">>>>>>docId" + docId);
            Document document = documentService.findByDocId(docId);
            if (docId == null) {
                return;
            }
            if (docId.contains("../")) {
                return;
            }
            String fileName = document.getDocName();
            String filePath = document.getStorageUrl();
            log.info("filePath" + filePath);
            File file = new File(filePath);
           String reName= document.getDocName();

            if (fileName != null) {
                // 如果文件存在，则进行下载
                if (file.exists()) {
                    // 配置文件下载
                    response.setHeader("content-type", "application/octet-stream");
                    response.setContentType("application/octet-stream");
                    // 下载文件能正常显示中文
                    try {
                        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                    // 实现文件下载
                    byte[] buffer = new byte[1024];

                    FileInputStream fis = null;
                    BufferedInputStream bis = null;
                    try {
                        fis = new FileInputStream(file);
                        bis = new BufferedInputStream(fis);
                        response.setHeader("Content-Length", fis.available() + "");
                        response.setContentType("application/octet-stream");
                        OutputStream os = response.getOutputStream();
                        int i = bis.read(buffer);
                        while (i != -1) {
                            os.write(buffer, 0, i);
                            i = bis.read(buffer);
                        }
                        log.info("下载成功!" + fileName);
                    } catch (Exception e) {
                        log.info("下载失败！！！!");
                    } finally {
                        if (bis != null) {
                            try {
                                bis.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        if (fis != null) {
                            try {
                                fis.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
        }
    }
         /*   //包含文件的路径。和名字
            String storageUrl = document.getStorageUrl();
            // path是指欲下载的文件的路径。
            File file = new File(storageUrl);
            // 取得文件名。
            String name = file.getName();
            // 取得文件的后缀名。
            String ext = name.substring(name.lastIndexOf(".") + 1).toUpperCase();
            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(storageUrl));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(name.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
*/
    /**
     * 文件上传
     * @param file      文件（必须）
     * @param uploader  上传者（必须）
     * @param desc      文件描述（选填）
     * @return
     */
    @PostMapping("/upload")
    public Result create(@RequestParam("file") MultipartFile file, String uploader,String desc,String docUuid)  {
        if (file.isEmpty()) {
            return new Result(false, StatusCode.ERROR,"上传失败，请选择文件");
        }
        if(StringUtils.isEmpty(uploader)){
            return new Result(false, StatusCode.ERROR,"上传失败，请确认uploader");
        }
        if(StringUtils.isEmpty(docUuid)){
            return new Result(false, StatusCode.ERROR,"上传失败，docUuid");
        }
        String fileName = file.getOriginalFilename();
        long fileSize= file.getSize();
        //String contentType = file.getContentType();
        //字尾。。。jpg
        String prefix=fileName.substring(fileName.lastIndexOf(".")+1);
        String prefile=fileName.substring(0,fileName.lastIndexOf("."));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String sj = sdf.format(new Date());
        String fileNameNew =prefile +sj +"."+prefix;//原文件名+时间+.jpg后缀
        File dirPath = new File("/storage" + File.separator + "document");
        //如果不存在文件夹，创建文件夹
        if(!dirPath.isDirectory()){
            log.info("文件夹不存在，创建" + uploadUrl);
            dirPath.mkdirs();}
        //文件路径
        String filePath = uploadUrl+ fileNameNew;
        //创建文件
        File dest = new File(filePath);
        try {
            //文件传送到
            file.transferTo(dest);
            Properties prop = System.getProperties();
            String os = prop.getProperty("os.name");
            if (os != null && os.toLowerCase().indexOf("linux") > -1) {
                Runtime.getRuntime().exec("chmod 644 " + uploadUrl +  "/"+  fileNameNew);
            }
        } catch (IOException e) {
            log.info(e.getMessage());
            return new Result(false, StatusCode.ERROR,"上传文件异常");
        }
        log.info("文件上传后>>>>存储数据库");
        Document document = new Document();
        document.setDocName(fileName);
        document.setDocSize((int) fileSize);
        document.setDocType(prefix);
        document.setDocUuid(docUuid);
        document.setStorageUrl(filePath);
        document.setUploadTime(LocalDateTime.now());
        document.setUploader(uploader);
        document.setDocDesc(desc);
        //储存方式 1 是公开。。0是私人
        document.setStorageType(0);
        //是否被删除1 存在   0逻辑删除
        document.setDeleted(1);
        documentService.addDocument(document);
        //返回地址值
        return new Result(true, StatusCode.OK,"上传成功",document);
    }

    /**多条件搜索数据
     * @param data
     * @return
     */
    @PostMapping(value = "/search" )
    public Result<Document> findList(@RequestBody String data){
        log.info("searchMap>>>>>" + data );
        JSONObject jsonObject = JSON.parseObject(data);
        String document = jsonObject.getString("data");
        Map map = JSON.parseObject(document);
        System.out.println("map>>" +map);
        Integer storageType = (Integer)map.get("storageType");
        //公开
       if (null == storageType){  map.put("storageType",0);}
        Integer page = jsonObject.getInteger("page");
        if (null ==page) {page=1;}
        Integer pageSize = jsonObject.getInteger("pageSize");
        if (null ==pageSize) {pageSize = 10;}
        log.info(">>>map" + map +">>>page" + page +">>>pageSize" + pageSize  );

        Page<Document> list = documentService.findList(map,page,pageSize);
        PageResult<Document> pageResult = new PageResult<>(list.getTotal(), list.getResult());
        return new Result<>(true, StatusCode.OK,"查询所有文件成功",pageResult);
    }

    @PostMapping("/update")
    public Result update(@RequestBody String data){
        log.info("更新文档"+data);
        if(StringUtils.isEmpty(data)){ return  new Result(false, StatusCode.ERROR,"参数为空");}
        Document document = JSONObject.parseObject(data, Document.class);
        document.setUploadTime(LocalDateTime.now());
       /* //删除数据库。并且需删除linux文件。
        //linux文件路径
        String storageUrl = document.getStorageUrl();
        if(!StringUtils.isEmpty(storageUrl)){
            File file = new File(storageUrl);
            if (file.exists()){file.delete();
                log.info("linux文件删除");}
        }*/
        //没有写地址。
        documentService.update(document);
        return new Result(true, StatusCode.OK,"更新成功");
    }








    @PostMapping("/deletereal" )
    public Result deleteReal(@RequestBody String data){
        log.info("删除"+data);
        if(StringUtils.isEmpty(data)){ return  new Result(false, StatusCode.ERROR,"参数为空");}
        JSONObject jsonObject = JSONObject.parseObject(data);
        String docId = jsonObject.getString("docId");
        if(null==docId){ return  new Result(false, StatusCode.ERROR,"参数id值有误");}
        Document byDocId = documentService.findByDocId(docId);
        //删除数据库。并且需删除linux文件。
        //linux文件路径
        String storageUrl = byDocId.getStorageUrl();
        if(!StringUtils.isEmpty(storageUrl)){
            File file = new File(storageUrl);
            if (file.exists()){file.delete();
            log.info("linux文件删除");}
        }
        documentService.deleteReal(byDocId.getId());

        return new Result(true, StatusCode.OK,"删除成功");
    }
    @PostMapping("/delete" )
    public Result delete(@RequestBody String data){
        log.info("逻辑删除"+data);
        if(StringUtils.isEmpty(data)){ return  new Result(false, StatusCode.ERROR,"参数为空");}
        JSONObject jsonObject = JSONObject.parseObject(data);
        String docId = jsonObject.getString("docId");
        if(null==docId){ return  new Result(false, StatusCode.ERROR,"参数id值有误");}
        Document byDocId = documentService.findByDocId(docId);
        byDocId.setDeleted(0);
        documentService.update(byDocId);
        return new Result(true, StatusCode.OK,"删除成功");
    }
    @PostMapping("/private" )
    public Result privateFile(@RequestBody String data){
        log.info("更新文档"+data);
        if(StringUtils.isEmpty(data)){ return  new Result(false, StatusCode.ERROR,"参数为空");}
        JSONObject jsonObject = JSONObject.parseObject(data);
        String docId = jsonObject.getString("docId");
        Document document = documentService.findByDocId(docId);
        document.setStorageType(0);
        document.setUploadTime(LocalDateTime.now());
        //没有写地址。
        documentService.update(document);
        return new Result(true, StatusCode.OK,"设置私有成功");
    }

    @PostMapping("/public" )
    public Result publicFile(@RequestBody String data){
        log.info("更新文档"+data);
        if(StringUtils.isEmpty(data)){ return  new Result(false, StatusCode.ERROR,"参数为空");}
        JSONObject jsonObject = JSONObject.parseObject(data);
        String docId = jsonObject.getString("docId");
        Document document = documentService.findByDocId(docId);
        //1公开。0个人
        document.setStorageType(1);
        document.setUploadTime(LocalDateTime.now());
        //没有写地址。
        documentService.update(document);
        return new Result(true, StatusCode.OK,"设置公开成功");
    }




    /**
     * 覆盖文件。上传
     * @param file      文件（必须）
     * @return
     */
    @PostMapping("/coverage")
    public Result coverage(@RequestParam("file") MultipartFile file,String docId)  {
        if (file.isEmpty()) {
            return new Result(false, StatusCode.ERROR,"覆盖失败，请选择文件");
        }
        if(null==docId){throw new RuntimeException("docId文件唯一ID，请检查");}
        String fileName = file.getOriginalFilename();
        long fileSize= file.getSize();
        //字尾。。。jpg
        String prefix=fileName.substring(fileName.lastIndexOf(".")+1);
        String prefile=fileName.substring(0,fileName.lastIndexOf("."));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String sj = sdf.format(new Date());
        String fileNameNew =prefile +sj +"."+prefix;//原文件名+时间+.jpg后缀
        File dirPath = new File("/storage" + File.separator + "document");
        //如果不存在文件夹，创建文件夹
        if(!dirPath.isDirectory()){
            log.info("文件夹不存在，创建" + uploadUrl);
            dirPath.mkdirs();}
        //文件路径
        String filePath = uploadUrl+ fileNameNew;
        //创建文件
        File dest = new File(filePath);
        try {
            //文件传送到
            file.transferTo(dest);
            Properties prop = System.getProperties();
            String os = prop.getProperty("os.name");
            if (os != null && os.toLowerCase().indexOf("linux") > -1) {
                Runtime.getRuntime().exec("chmod 644 " + uploadUrl +  "/"+  fileNameNew);
            }
        } catch (IOException e) {
            log.info(e.getMessage());
            return new Result(false, StatusCode.ERROR,"上传文件异常");
        }
        log.info("文件上传后>>>>存储数据库");
        Document document = new Document();
        document.setDocName(fileName);
        document.setDocSize((int) fileSize);
        document.setDocType(prefix);
        document.setDocUuid(sj + fileSize);
        document.setStorageUrl(filePath);
        document.setUploadTime(LocalDateTime.now());
        //储存方式 1 是公开。。0 是私人
        document.setStorageType(0);
        //是否被删除  1 存在   0逻辑删除
        document.setDeleted(1);
        documentService.addDocument(document);
        //返回地址值
        return new Result(true, StatusCode.OK,"上传成功",document);
    }
}
